package com.kyleswebspace.propertyanalyzer.gui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.ItemEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.border.TitledBorder;

import com.kyleswebspace.parser.FieldParser;
import com.kyleswebspace.propertyanalyzer.config.ArcaFont;
import com.kyleswebspace.propertyanalyzer.config.ColorBox;
import com.kyleswebspace.propertyanalyzer.model.DataModel;

public class IncomePanel extends JPanel implements Updateable, 
KeyListener, ActionListener, MouseListener {

	/**
	 * 
	 */
	private static final long serialVersionUID = 3453626200831760714L;

	private DataModel dm;
	private FocusMediator fm;

	private JLabel annualLabel;
	private JLabel rentLabel;
	private JTextField rentField;
	private JLabel parkingLabel;
	private JTextField parkingField;
	private JLabel laundryLabel;
	private JTextField laundryField;
	private JLabel otherLabel;
	private JTextField otherField;
	private JLabel goiLabel;
	private JTextField goiField;
	private JLabel vacancyLabel;
	private JTextField vacancyField;
	private JTextField vacancyFieldB;
	private JLabel effectiveGOILabel;
	private JTextField effectiveGOIField;
	private JButton rentButton;
	
	private final Color overriddenColor = ColorBox.overriddenColor;
	private final Color editableColor = ColorBox.fieldColor;
	private Color innerPanelColor = ColorBox.innerPanelColor;
	private Font appFont = ArcaFont.appFont;

	public IncomePanel(DataModel dm, FocusMediator fm) {
		this.dm = dm;
		this.fm = fm;
		dm.register(this);

		this.setLayout(new GridBagLayout());
		TitledBorder title;
		title = BorderFactory.createTitledBorder("Income");
		this.setBorder(title);
		this.setBackground(innerPanelColor);

		GridBagConstraints constraints = new GridBagConstraints();
		constraints.ipadx = 20; // PADDING

		// annual label
		annualLabel = new JLabel("Annual ");
		annualLabel.setFont(appFont);
		annualLabel.setHorizontalAlignment(JTextField.RIGHT);
		constraints.gridx = 3;
		constraints.gridy = 0;
		constraints.gridwidth = 1;
		constraints.anchor = GridBagConstraints.EAST;
		this.add(annualLabel, constraints);

		// rent
		rentLabel = new JLabel("Rent");
		rentLabel.setFont(appFont);
		constraints.gridx = 0;
		constraints.gridy = 1;
		constraints.gridwidth = 3;
		constraints.anchor = GridBagConstraints.WEST;
		this.add(rentLabel, constraints);
		rentField = new JTextField(4);
		fm.setRentField(rentField);
		rentField.addFocusListener(this);
		rentField.addKeyListener(this);
		rentField.addMouseListener(this);
		rentField.setFont(appFont);
		rentField.setHorizontalAlignment(JTextField.RIGHT);
		constraints.gridwidth = 1;
		constraints.gridx = 3;
		constraints.anchor = GridBagConstraints.EAST;
		rentField.setBackground(ColorBox.overridableColor);
		this.add(rentField, constraints);
		rentButton = new JButton("Monthly Rents");
		rentButton.addActionListener(this);
		Dimension preferredSize = new Dimension(90,15);
		rentButton.setPreferredSize(preferredSize);
		rentButton.setFont(appFont);
		constraints.gridx = 2;
		constraints.anchor = GridBagConstraints.EAST;
		this.add(rentButton, constraints);

		// parking
		parkingLabel = new JLabel("Parking");
		parkingLabel.setFont(appFont);
		constraints.gridx = 0;
		constraints.gridy = 2;
		constraints.gridwidth = 3;
		constraints.anchor = GridBagConstraints.WEST;
		this.add(parkingLabel, constraints);
		parkingField = new JTextField(4);
		fm.setParkingField(parkingField);
		parkingField.addFocusListener(this);
		parkingField.addKeyListener(this);
		parkingField.setFont(appFont);
		parkingField.setHorizontalAlignment(JTextField.RIGHT);
		constraints.gridwidth = 1;
		constraints.gridx = 3;
		constraints.anchor = GridBagConstraints.EAST;
		parkingField.setBackground(editableColor);
		this.add(parkingField, constraints);

		// laundry
		laundryLabel = new JLabel("Laundry");
		laundryLabel.setFont(appFont);
		constraints.gridx = 0;
		constraints.gridy = 3;
		constraints.gridwidth = 3;
		constraints.anchor = GridBagConstraints.WEST;
		this.add(laundryLabel, constraints);
		laundryField = new JTextField(4);
		fm.setLaundryField(laundryField);
		laundryField.addFocusListener(this);
		laundryField.addKeyListener(this);
		laundryField.setFont(appFont);
		laundryField.setHorizontalAlignment(JTextField.RIGHT);
		constraints.gridwidth = 1;
		constraints.gridx = 3;
		constraints.anchor = GridBagConstraints.EAST;
		laundryField.setBackground(editableColor);
		this.add(laundryField, constraints);

		// other
		otherLabel = new JLabel(
				"Other                                             +");
		otherLabel.setFont(appFont);
		constraints.gridx = 0;
		constraints.gridy = 4;
		constraints.gridwidth = 3;
		constraints.anchor = GridBagConstraints.WEST;
		this.add(otherLabel, constraints);
		otherField = new JTextField(4);
		fm.setOtherField(otherField);
		otherField.addFocusListener(this);
		otherField.addKeyListener(this);
		otherField.setFont(appFont);
		otherField.setHorizontalAlignment(JTextField.RIGHT);
		constraints.gridwidth = 1;
		constraints.gridx = 3;
		constraints.anchor = GridBagConstraints.EAST;
		otherField.setBackground(editableColor);
		this.add(otherField, constraints);

		// separator
		constraints.gridx = 0;
		constraints.gridwidth = 4;
		constraints.gridy = 5;
		constraints.fill = GridBagConstraints.HORIZONTAL;
		this.add(new JSeparator(SwingConstants.HORIZONTAL), constraints);
		constraints.fill = GridBagConstraints.NONE;

		// GOI
		goiLabel = new JLabel("Gross Operating Income (GOI)      ");
		goiLabel.setFont(appFont);
		constraints.gridx = 0;
		constraints.gridy = 6;
		constraints.gridwidth = 3;
		constraints.anchor = GridBagConstraints.WEST;
		this.add(goiLabel, constraints);
		goiField = new JTextField(4);
		goiField.addFocusListener(this);
		goiField.setFocusable(false);
		goiField.setFont(appFont);
		goiField.setHorizontalAlignment(JTextField.RIGHT);
		constraints.gridwidth = 1;
		constraints.gridx = 3;
		constraints.anchor = GridBagConstraints.EAST;
		this.add(goiField, constraints);

		// vacancy rate
		vacancyLabel = new JLabel("Vacancy Rate");
		vacancyLabel.setFont(appFont);
		constraints.gridx = 0;
		constraints.gridy = 7;
		constraints.gridwidth = 3;
		constraints.anchor = GridBagConstraints.WEST;
		this.add(vacancyLabel, constraints);
		vacancyField = new JTextField(2);
		fm.setVacancyRateField(vacancyField);
		vacancyField.addFocusListener(this);
		vacancyField.addKeyListener(this);
		vacancyField.setFont(appFont);
		vacancyFieldB = new JTextField(4);
		vacancyFieldB.addFocusListener(this);
		vacancyFieldB.setFocusable(false);
		vacancyFieldB.setFont(appFont);
		vacancyField.setHorizontalAlignment(JTextField.RIGHT);
		vacancyFieldB.setHorizontalAlignment(JTextField.RIGHT);
		constraints.gridwidth = 1;
		constraints.gridx = 2;
		constraints.anchor = GridBagConstraints.EAST;
		vacancyField.setBackground(editableColor);
		this.add(vacancyField, constraints);
		constraints.gridwidth = 1;
		constraints.gridx = 3;
		constraints.anchor = GridBagConstraints.EAST;
		this.add(vacancyFieldB, constraints);

		// separator
		constraints.gridx = 0;
		constraints.gridwidth = 4;
		constraints.gridy = 8;
		constraints.fill = GridBagConstraints.HORIZONTAL;
		this.add(new JSeparator(SwingConstants.HORIZONTAL), constraints);
		constraints.fill = GridBagConstraints.NONE;

		// effective GOI
		effectiveGOILabel = new JLabel("Effective GOI");
		effectiveGOILabel.setFont(appFont);
		constraints.gridx = 0;
		constraints.gridy = 9;
		constraints.gridwidth = 3;
		constraints.anchor = GridBagConstraints.WEST;
		this.add(effectiveGOILabel, constraints);
		effectiveGOIField = new JTextField(4);
		effectiveGOIField.addFocusListener(this);
		effectiveGOIField.setFocusable(false);
		effectiveGOIField.setFont(appFont);
		effectiveGOIField.setHorizontalAlignment(JTextField.RIGHT);
		constraints.gridwidth = 1;
		constraints.gridx = 3;
		constraints.anchor = GridBagConstraints.EAST;
		this.add(effectiveGOIField, constraints);
		
		//update overridden values, if any
		if(dm.isOverrideRent()) {
			rentField.setBackground(overriddenColor);
		}

		updateFields();
	}

	public void updateFields() {
		this.rentField.setText(dm.getRent());
		this.parkingField.setText(dm.getParking());
		this.laundryField.setText(dm.getLaundry());
		this.otherField.setText(dm.getOther());
		this.goiField.setText(dm.getGoi());
		this.vacancyField.setText(dm.getVacancyRateA() + "%");
		this.vacancyFieldB.setText(dm.getVacancyRateB());
		this.effectiveGOIField.setText(dm.getEffectiveGOI());
	}

	public void updateModel() {
		if(dm.isOverrideRent()) {
			dm.setRent(FieldParser.parseInteger(this.rentField.getText()));
		}
		dm.setParking(FieldParser.parseInteger(this.parkingField.getText()));
		dm.setLaundry(FieldParser.parseInteger(this.laundryField.getText()));
		dm.setOther(FieldParser.parseInteger(this.otherField.getText()));
		dm.setVacancyRateA(FieldParser
				.parseDecimal(this.vacancyField.getText()));

		dm.updateInterface();		
	}
	
	public void itemStateChanged(ItemEvent e) {

	}

	@Override
	public void focusGained(FocusEvent e) {
		if (e.getSource() instanceof JTextField) {
			JTextField focusedField = (JTextField) e.getSource();
			focusedField.selectAll();
		}

	}

	@Override
	public void focusLost(FocusEvent e) {
		updateModel();
	}

	@Override
	public void keyPressed(KeyEvent e) {
		if (e.getSource() == rentField) {
			if (e.getKeyCode() == KeyEvent.VK_DOWN) {
				fm.getParkingField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_UP) {
				fm.getOtherExpensesField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
				fm.getAddressField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
				fm.getPercentPPAField().requestFocus();
			}
		} else if (e.getSource() == parkingField) {
			if (e.getKeyCode() == KeyEvent.VK_DOWN) {
				fm.getLaundryField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_UP) {
				fm.getRentField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
				fm.getNumberDoorsField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
				fm.getPercentPPAField().requestFocus();
			}
		} else if (e.getSource() == laundryField) {
			if (e.getKeyCode() == KeyEvent.VK_DOWN) {
				fm.getOtherField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_UP) {
				fm.getParkingField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
				fm.getAskingPriceField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
				fm.getPaymentTypeAField().requestFocus();
			}
		} else if (e.getSource() == otherField) {
			if (e.getKeyCode() == KeyEvent.VK_DOWN) {
				fm.getVacancyRateField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_UP) {
				fm.getLaundryField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
				fm.getAskingPriceField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
				fm.getPaymentTypeAField().requestFocus();
			}
		} else if (e.getSource() == vacancyField) {
			if (e.getKeyCode() == KeyEvent.VK_DOWN) {
				fm.getPropertyTaxesField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_UP) {
				fm.getOtherField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_LEFT) {
				fm.getPurchasePriceField().requestFocus();
			} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
				fm.getInterestRateAField().requestFocus();
			}
		}
		if (e.getKeyCode() == KeyEvent.VK_ENTER) {
			updateModel();
		}
	}

	@Override
	public void keyReleased(KeyEvent e) {

	}

	@Override
	public void keyTyped(KeyEvent e) {

	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == rentButton) {
			RentFrame rf = new RentFrame(dm, fm);
		}
	}

	@Override
	public void mouseClicked(MouseEvent e) {
		if (e.getSource() == rentField
				&& rentField.getBackground() != overriddenColor) {
			int response = JOptionPane.showConfirmDialog(this,
					"Would you like to override the Rent field instead of entering individual apartment rents?",
					"Override Rent?", JOptionPane.YES_NO_OPTION);
			// if response is 'yes'
			if (response == 0) {
				// change field color to overridden color
				rentField.setBackground(overriddenColor);

				// update DataModel flag
				dm.setOverrideRent(true);

				// update JMenuCheckBox
				fm.getRentOverride().setSelected(true);
			}
		}
		
	}

	@Override
	public void mouseEntered(MouseEvent arg0) {
		
	}

	@Override
	public void mouseExited(MouseEvent arg0) {
		
	}

	@Override
	public void mousePressed(MouseEvent arg0) {
		
	}

	@Override
	public void mouseReleased(MouseEvent arg0) {
		
	}
}
